package com.hup.sokoban.presenter;

import com.hup.sokoban.constant.MapConstant;
import com.hup.sokoban.model.common.MapItem;
import com.hup.sokoban.mvp.MapDesignerMvp.MapDesignerPresenter;
import com.hup.utils.commons.AssertApp;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author hugan
 * @date 2020/4/30
 */
@Log4j2
@Lazy
@Component
public class MapDesignerPresenterImpl implements MapDesignerPresenter {

    @Override
    public List<MapItem> reloadMapList() {
        File dir = new File(MapConstant.MAP_DIR);
        ArrayList<MapItem> res = new ArrayList<>();
        if (!dir.exists()) return res;

        //只加载已完成的地图
        File[] mapFiles = dir.listFiles((dir1, name) -> name.endsWith(MapConstant.EXT) || name.endsWith(MapConstant.EXT_DESIGNING));
        if (mapFiles == null) return res;
        for (File mapFile : mapFiles) {
            MapItem item = MapItem.readFromFile(mapFile);
            res.add(item);
        }
        log.info("map数量={}", res.size());
        return res;
    }

    @Override
    public boolean isSame(MapItem curMap, MapItem lastLoadedMap) {
        if (lastLoadedMap == null) {
            return false;//应该不会发生
        }
        if (!Objects.equals(curMap.getName(), lastLoadedMap.getName())
                || !Objects.equals(curMap.getDescription(), lastLoadedMap.getDescription())
                || !Objects.equals(curMap.getBackgroundImage(), lastLoadedMap.getBackgroundImage())
                || !Objects.equals(curMap.getWidth(), lastLoadedMap.getWidth())
                || !Objects.equals(curMap.getHeight(), lastLoadedMap.getHeight())
                || !Objects.equals(curMap.getMap().length, lastLoadedMap.getMap().length)
                ) {
            return false;
        }

        for (int i = 0; i < curMap.getMap().length; i++) {
            if (curMap.getMap()[i] != lastLoadedMap.getMap()[i]) return false;
        }
        return true;
    }

    @Override
    public void copyMapData(MapItem curMap, MapItem source) {
        int width = source.getWidth();
        int height = source.getHeight();
        int[] map = new int[source.getMap().length];
        System.arraycopy(source.getMap(), 0, map, 0, map.length);
        curMap.setWidth(width);
        curMap.setHeight(height);
        curMap.setMap(map);
        curMap.updateMapSafeFields();
    }

    @Override
    public void doDelete(MapItem mapItem) {
        String path = mapItem.getPath();
        File file = new File(path);
        if (file.exists()) {
            boolean delete = file.delete();
            if (!delete) {
                log.error("删除失败?, {}", path);
            }
        } else {
            //用户手工删除文件
            log.info("文件不存在:{}", path);
        }
        deleteRecords(mapItem);
    }

    @Override
    public boolean needDeleteMapRecords(MapItem curMap, MapItem lastLoadedMap) {
        if (!curMap.isPlaying() && !curMap.isWinning()) {
            //没有[游戏记录]
            log.debug("无游戏记录");
            return false;
        }

        if (lastLoadedMap.getNotSafeMsg() != null || lastLoadedMap.getAliArea().isEmpty()) {
            log.debug("旧地图未完成,但有游戏记录??");
            return true;
        }

        if (curMap.getNotSafeMsg() != null || curMap.getAliArea().isEmpty()) {
            log.debug("新地图未完成");
            return true;
        }

        boolean equalsAliArea = curMap.getAliArea().equals(lastLoadedMap.getAliArea());
        if (!equalsAliArea) {
            log.debug("阿狸区域变化了");
        } else {
            log.debug("可能有其他关卡字段变化,但不用删除记录");
        }
        return !equalsAliArea;
    }

    @Override
    public void checkAndSaveMap(MapItem mapItem, MapItem lastLoadedMap) {
        AssertApp.notEmptyString(mapItem.getName(), "请输入[关卡名]");
        if (mapItem.getBackgroundImage() != null) AssertApp.exists(mapItem.getBackgroundImage());

        if (needDeleteMapRecords(mapItem, lastLoadedMap)) {
            deleteRecords(mapItem);
        }
        mapItem.doSaveFile();
    }

    private void deleteRecords(MapItem mapItem) {
        log.info("删除游戏记录.st");
        for (String ext : new String[]{MapConstant.EXT_PROGRESS, MapConstant.EXT_WINNING}) {
            File file = new File(MapConstant.MAP_DIR + mapItem.getName() + ext);
            if (file.exists()) {
                boolean delete = file.delete();
                if (!delete) {
                    log.warn("删除失败?={}", file);
                } else {
                    log.warn("已删除={}", file);
                }
            }
        }
    }

}
